//
//  SKMainScene.swift
//  SpriteKitDemo
//
//  Created by lizhijun on 2023/4/18.
//

import UIKit
import SpriteKit
import Foundation
enum SKRoleCategory:UInt32{
   case SKRoleCategoryPlayerBullet = 1
   case SKRoleCategoryFoePlayer = 4
   case SKRoleCategoryplayerRole = 8
   case SKRoleCategoryFoeBullet = 16
}
class SKMainScene: SKScene, SKPhysicsContactDelegate {
    
    var nodeArray:[SKNode] = []
    private(set) lazy var contentView: SceneView = {
        let view = SceneView()
        view.touchesMovedClosure = {
            [weak self](touchs,event)  in
            guard let self = self else {
                return
            }
            self.touchesMoved(touchs, with: event)
        }
        return view
    }()
    var playerRole:AJSpriteNode?
    var foeRole:AJSpriteNode?
    override init(size: CGSize) {
        super.init(size: size)
      
       
    }
    func setUpUI(){
        contentView.frame = CGRect(x: 0, y: 0, width: size.width, height: size.height)
        initPhysicsWorld()
        initBackground()
        initplayerRole()
        initFoeRole()
    }
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    private func initPhysicsWorld(){
        self.physicsWorld.contactDelegate = self
        self.physicsWorld.gravity = CGVectorMake(0, 0)
    }
    
    //玩家
   private func initplayerRole() {
        playerRole = AJSpriteNode()
       playerRole?.mark = 100
       guard let playerRole = playerRole else {return}
        playerRole.position = CGPoint(x: 160, y: 50)
        playerRole.size = CGSize(width: 100, height: 100)
       //setUpNodeContent方法实现contentView添加到SceneView上并实现坐标转换
       setUpNodeContent(node: playerRole, imgStr: "bear")
        playerRole.zPosition = 1
       playerRole.physicsBody = SKPhysicsBody(rectangleOf: CGSize(width: (playerRole.size.width )-20, height: playerRole.size.height ))
        playerRole.physicsBody?.categoryBitMask = SKRoleCategory.SKRoleCategoryplayerRole.rawValue
        playerRole.physicsBody?.collisionBitMask = SKRoleCategory.SKRoleCategoryFoeBullet.rawValue
        playerRole.physicsBody?.contactTestBitMask = SKRoleCategory.SKRoleCategoryFoeBullet.rawValue
       addChild(playerRole)
      
       firingBullets(bulletType: 0)
    }
    //敌人
    private func initFoeRole() {
         
        foeRole = AJSpriteNode()
        guard let foeRole = foeRole else {return}
        foeRole.name = "foePlane"
        foeRole.size = CGSize(width: 64, height: 60)
        foeRole.position = CGPoint(x: self.size.width*0.5, y: self.size.height - APPTool.topSafeAreaMargin - foeRole.size.height*0.5)
        
        setUpNodeContent(node: foeRole, imgStr: nil)
        foeRole.contentView?.imgView.image = UIImage(named: "monster")
        foeRole.physicsBody?.isDynamic = true
        //categoryBitMask  设置物理体标识符
        foeRole.physicsBody?.categoryBitMask = SKRoleCategory.SKRoleCategoryFoePlayer.rawValue
        //collisionBitMask  设置碰撞标识符  (非零 决定了物体能否碰撞反应)
        foeRole.physicsBody?.collisionBitMask = SKRoleCategory.SKRoleCategoryplayerRole.rawValue
        //contactTestBitMask 设置可以那类物理体碰撞  ->触发检测碰撞事件
        foeRole.physicsBody?.contactTestBitMask = SKRoleCategory.SKRoleCategoryplayerRole.rawValue
        self.addChild(foeRole)
        foeRoleAction()
        firingBullets(bulletType: 1)
     }
    
    
    
    private func initBackground(){
        let imgView = UIImageView(image: UIImage(named: "bg0"))
        imgView.isUserInteractionEnabled = true
        imgView.frame = contentView.bounds
        contentView.addSubview(imgView)
    }
    
    private func foeRoleAction(){
       
        let leftAction = SKAction.moveTo(x: 0 + (foeRole?.size.width ?? 0)*0.5, duration: 1)
        let rightAction = SKAction.moveTo(x:SCREENW - (foeRole?.size.width ?? 0)*0.5 , duration: 1)
        let moveSequence = SKAction.sequence([leftAction, rightAction])

        let repeatAction = SKAction.repeatForever(moveSequence) //SKAction.repeatForever(action)
        foeRole?.run(repeatAction)
    }
    //执行炮弹动画
  private  func firingBullets(bulletType: Int) {
        
        let action = SKAction.run {
            self.createBullets( bulletType)
        }
        let interval = SKAction.wait(forDuration: 0.2)
        //场景循环炮弹的动画
        self.run(SKAction.repeatForever(SKAction.sequence([action, interval])), withKey: "Bullets\(bulletType)")
    }
    
    //敌我子弹
    func createBullets(_ bulletType: Int) {
        guard let playerRole = playerRole, let foeRole = foeRole else{return}
        var image:UIImage!
        var categoryBitMask:UInt32 = 0
        var collisionBitMask:UInt32 = 0
        var contactTestBitMask:UInt32 = 0
        
        if bulletType == 0{
           image = APPTool.imageWithColor(.green, size: CGSize(width: 6, height: 6))
             categoryBitMask = SKRoleCategory.SKRoleCategoryPlayerBullet.rawValue
             collisionBitMask = SKRoleCategory.SKRoleCategoryFoePlayer.rawValue | SKRoleCategory.SKRoleCategoryFoeBullet.rawValue
             contactTestBitMask = SKRoleCategory.SKRoleCategoryFoePlayer.rawValue | SKRoleCategory.SKRoleCategoryFoeBullet.rawValue
            
        }else{
            image = APPTool.imageWithColor(.red, size: CGSize(width: 6, height: 6))
            categoryBitMask = SKRoleCategory.SKRoleCategoryFoeBullet.rawValue
            collisionBitMask = SKRoleCategory.SKRoleCategoryplayerRole.rawValue | SKRoleCategory.SKRoleCategoryPlayerBullet.rawValue
            contactTestBitMask = SKRoleCategory.SKRoleCategoryplayerRole.rawValue | SKRoleCategory.SKRoleCategoryPlayerBullet.rawValue
            
        }
        
        let bullet = AJSpriteNode(texture:SKTexture(image: image))
        bullet.physicsBody = SKPhysicsBody(rectangleOf: bullet.size)
        
        bullet.physicsBody?.categoryBitMask = categoryBitMask
        bullet.physicsBody?.collisionBitMask = collisionBitMask
        bullet.physicsBody?.contactTestBitMask = contactTestBitMask
        bullet.zPosition = 1
        var actionMove:SKAction!
        if bulletType == 0{
            bullet.position = CGPoint(x: playerRole.position.x, y: playerRole.position.y + (playerRole.size.height/2))
            addChild(bullet)
            
             actionMove = SKAction.move(to: CGPoint(x: playerRole.position.x, y: size.height), duration: 2)
        }else
        {
            bullet.position = CGPoint(x: foeRole.position.x, y: foeRole.position.y - (foeRole.size.height/2))
            addChild(bullet)
            
             actionMove = SKAction.move(to: CGPoint(x: foeRole.position.x, y: 0), duration: 2)
        }
        setUpNodeContent(node: bullet, imgStr: nil)
        bullet.contentView?.imgView.image = image
        let actionMoveDone = SKAction.removeFromParent()
        //这里记得移除对应的节点
        weak var weakBullet = bullet
        bullet.run(SKAction.sequence([actionMove,actionMoveDone])) {
            [weak self] in
            guard let self = self else {
                return
            }
            self.nodeArray.removeAll { node in
                node == weakBullet
            }
            weakBullet?.removeContentView()
        }
       
    }
    
   
    
    func didBegin(_ contact: SKPhysicsContact) {
        
        if (contact.bodyA.categoryBitMask & SKRoleCategory.SKRoleCategoryFoeBullet.rawValue != 0 || contact.bodyB.categoryBitMask & SKRoleCategory.SKRoleCategoryFoeBullet.rawValue != 0) && (contact.bodyA.categoryBitMask & SKRoleCategory.SKRoleCategoryPlayerBullet.rawValue != 0 || contact.bodyB.categoryBitMask & SKRoleCategory.SKRoleCategoryPlayerBullet.rawValue != 0){
            contact.bodyA.node?.removeFromParent()
            contact.bodyB.node?.removeFromParent()
            guard let spriteNodeB  = contact.bodyB.node as? AJSpriteNode else{return}
            spriteNodeB.removeFromParent()
            nodeArray.removeAll { node in
                spriteNodeB == node
            }
            spriteNodeB.removeContentView()
            guard let spriteNodeA  = contact.bodyA.node as? AJSpriteNode else{return}
            spriteNodeA.removeFromParent()
            nodeArray.removeAll { node in
                spriteNodeA == node
            }
            spriteNodeA.removeContentView()
        } else if (contact.bodyA.categoryBitMask & SKRoleCategory.SKRoleCategoryFoeBullet.rawValue != 0 || contact.bodyB.categoryBitMask & SKRoleCategory.SKRoleCategoryFoeBullet.rawValue != 0) && (contact.bodyA.categoryBitMask & SKRoleCategory.SKRoleCategoryplayerRole.rawValue != 0 || contact.bodyB.categoryBitMask & SKRoleCategory.SKRoleCategoryplayerRole.rawValue != 0) {
            
            if contact.bodyA.categoryBitMask == SKRoleCategory.SKRoleCategoryFoeBullet.rawValue {
                guard let spriteNode  = contact.bodyA.node as? AJSpriteNode else{return}
                spriteNode.removeFromParent()
                nodeArray.removeAll { node in
                    spriteNode == node
                }
                spriteNode.removeContentView()
                
                guard let spriteNodeB  = contact.bodyB.node as? AJSpriteNode else{return}
                spriteNodeB.getshot()
                
            }else if contact.bodyB.categoryBitMask == SKRoleCategory.SKRoleCategoryFoeBullet.rawValue {
                guard let spriteNode  = contact.bodyB.node as? AJSpriteNode else{return}
                spriteNode.removeFromParent()
                nodeArray.removeAll { node in
                    spriteNode == node
                }
                spriteNode.removeContentView()
                
                guard let spriteNodeA  = contact.bodyA.node as? AJSpriteNode else{return}
                spriteNodeA.getshot()
            }
        }
        else if (contact.bodyA.categoryBitMask & SKRoleCategory.SKRoleCategoryPlayerBullet.rawValue != 0 || contact.bodyB.categoryBitMask & SKRoleCategory.SKRoleCategoryPlayerBullet.rawValue != 0) && (contact.bodyA.categoryBitMask & SKRoleCategory.SKRoleCategoryFoePlayer.rawValue != 0 || contact.bodyB.categoryBitMask & SKRoleCategory.SKRoleCategoryFoePlayer.rawValue != 0) {
            if contact.bodyA.categoryBitMask == SKRoleCategory.SKRoleCategoryPlayerBullet.rawValue {
                contact.bodyA.node?.removeFromParent()
            }else if contact.bodyB.categoryBitMask == SKRoleCategory.SKRoleCategoryPlayerBullet.rawValue {
                contact.bodyB.node?.removeFromParent()
                
            }
        }
        
    }
    
    private func setUpNodeContent(node:AJSpriteNode,imgStr:String?){
        if let imgStr = imgStr{
            node.contentView?.imgView.image =  OCTool.image(toTransparent: imgStr, deleteWhite: false)
        }
        let point = view?.convert(node.position, from: self) ?? .zero
        node.contentView?.frame = CGRect(x: 0, y: 0, width: node.size.width, height: node.size.height)
        node.contentView?.AJCenterY = point.y
        node.contentView?.AJCenterX = point.x
        if let nodeContentView = node.contentView{
            contentView.addSubview(nodeContentView)
        }
        nodeArray.append(node)
    }
    
    
}
  

class SceneView:UIView{
    var touchesMovedClosure:((_ touches: Set<UITouch>,_ event: UIEvent?)->Void)?
    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?){
        self.touchesMovedClosure?(touches, event)
    }
}
